#include "../mqserver/mq_route.hpp"
#include <gtest/gtest.h>

class RouteTest : public testing::Environment
{
public:
    void SetUp() override
    {
        LOG(DEBUG, "测试环境初始化ing...\n");
    }

    void TearDown() override
    {
        LOG(DEBUG, "测试环境清理中ing...\n");
    }
};

TEST(RouteTest, routingkey_test)
{
    std::string b1 = "new.music.pop";
    std::string b2 = "new..music.pop";
    std::string b3 = "new.,music.pop";     // false
    std::string b4 = "new.music——123.pop"; // false
    std::string b5 = "new.music_123.pop";
    std::string b6 = "New.Music.pop";

    ASSERT_EQ(MQ::Router::isLegalRoutingKey(b1), true);
    ASSERT_EQ(MQ::Router::isLegalRoutingKey(b2), true);
    ASSERT_EQ(MQ::Router::isLegalRoutingKey(b3), false);
    ASSERT_EQ(MQ::Router::isLegalRoutingKey(b4), false);
    ASSERT_EQ(MQ::Router::isLegalRoutingKey(b5), true);
    ASSERT_EQ(MQ::Router::isLegalRoutingKey(b6), true);
}

TEST(RouteTest, bindingkey_test)
{
    std::string b1 = "new.music.pop";
    std::string b2 = "new..music.pop";
    std::string b3 = "new.,music.pop";     // false
    std::string b4 = "new.music——123.pop"; // false
    std::string b5 = "new.music*123.pop";  // false
    std::string b6 = "New.Music.pop";
    std::string b7 = "New.*#.pop";     // false
    std::string b8 = "new.music.*.#";  // falseMQ::
    std::string b9 = "new.music.#.#";  // false
    std::string b10 = "new.music.#.*"; // false
    std::string b11 = "new.music.*.*";

    ASSERT_EQ(MQ::Router::isLegalBindingKey(b1), true);
    ASSERT_EQ(MQ::Router::isLegalBindingKey(b2), true);
    ASSERT_EQ(MQ::Router::isLegalBindingKey(b3), false);
    ASSERT_EQ(MQ::Router::isLegalBindingKey(b4), false);
    ASSERT_EQ(MQ::Router::isLegalBindingKey(b5), false);
    ASSERT_EQ(MQ::Router::isLegalBindingKey(b6), true);
    ASSERT_EQ(MQ::Router::isLegalBindingKey(b7), false);
    ASSERT_EQ(MQ::Router::isLegalBindingKey(b8), false);
    ASSERT_EQ(MQ::Router::isLegalBindingKey(b9), false);
    ASSERT_EQ(MQ::Router::isLegalBindingKey(b10), false);
    ASSERT_EQ(MQ::Router::isLegalBindingKey(b11), true);
}

TEST(RouteTest, route_test)
{
    std::vector<std::string> bkeys = {
        "aaa",
        "aaa.bbb",
        "aaa.bbb",
        "aaa.bbb",
        "aaa.#.bbb",
        "aaa.bbb.#",
        "#.bbb.ccc",
        "aaa.bbb.ccc",
        "aaa.*",
        "aaa.*.bbb",
        "*.aaa.bbb",
        "#",
        "aaa.#",
        "aaa.#",
        "aaa.#.ccc",
        "aaa.#.ccc",
        "aaa.#.ccc",
        "#.ccc",
        "#.ccc",
        "aaa.#.ccc.ccc",
        "aaa.#.bbb.*.bbb"
    };
    std::vector<std::string> rkeys = {
        "aaa",
        "aaa.bbb",
        "aaa.bbb.ccc",
        "aaa.ccc",
        "aaa.bbb.ccc",
        "aaa.ccc.bbb",
        "aaa.bbb.ccc.ddd",
        "aaa.bbb.ccc",
        "aaa.bbb",
        "aaa.bbb.ccc",
        "aaa.bbb",
        "aaa.bbb.ccc",
        "aaa.bbb",
        "aaa.bbb.ccc",
        "aaa.ccc",
        "aaa.bbb.ccc",
        "aaa.aaa.bbb.ccc",
        "ccc",
        "aaa.bbb.ccc",
        "aaa.bbb.ccc.ccc.ccc",
        "aaa.ddd.ccc.bbb.eee.bbb"
    };
    std::vector<bool> result = {
        true,
        true,
        false,
        false,
        false,
        false,
        false,
        true,
        true,
        false,
        false,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true,
        true
    };
    for (int i = 0; i < bkeys.size(); i++)
    {
        if (MQ::Router::route(MQ::ExchangeType::TOPIC, rkeys[i], bkeys[i]) != result[i])
        {
            std::cout << "出错！！！！！！！！" << i << std::endl;
            std::cout << rkeys[i] << std::endl;
            std::cout << bkeys[i] << std::endl;
            std::cout << result[i] << std::endl;
            std::cout << MQ::Router::route(MQ::ExchangeType::TOPIC, rkeys[i], bkeys[i]) << std::endl;
        }
        ASSERT_EQ(MQ::Router::route(MQ::ExchangeType::TOPIC, rkeys[i], bkeys[i]), result[i]);
        
    }
}

int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    testing::AddGlobalTestEnvironment(new RouteTest);
    RUN_ALL_TESTS();
    return 0;
}